/**
 * User: Phil
 * Date: 10/17/11
 * Time: 10:03 PM
 */

//A Player has a Deck, a Hand, a Discard pile, and a Playfield

//Event documentation (event: args sent)
//- onDeckChanged: player index, new deck size
//- onDraw: player index, card drawn
//- onReclaim: player index
//- onDiscard: player index, card discarded
//- onPlayCard: player index, card played
//- onNewPlayer: player index, player name, actions, money, buys

//A deck functions as a simple FIFO stack, with more deck-like nomenclature:
//draw = pop, put = push
var Deck = Class.extend({
	init: function(player) {
		this.player = player;
		this.cards = new Array();
	},
	draw: function(quantity) {
		//Check deck size to see if we have enough.
		//If not, shuffle discard pile and put under deck
		if(this.cards.length <= quantity) {
			this.reclaimDiscardPile();
		}

		//Draw requested amount of cards
		for(var x = 0;x < quantity;x++) {
			var newCard = this.cards.shift();
			this.player.hand.cards.push(newCard);

			//Fire event
			$("#player_events").trigger("onDeckChanged", [this.player.index, this.cards.length]);

			//Fire event
			$("#player_events").trigger("onDraw", [this.player.index, newCard]);
		}
	},
	//Supports passing in an arbitrary amount of Cards
	put: function() {
		$.each(arguments, function(index, value) {
			this.cards.push(value);
		});
	},
	reclaimDiscardPile: function() {
		//Shuffle discard pile
		this.player.discardPile.cards.shuffle();
		
		//Add back to bottom of deck
		$.each(this.player.discardPile.cards, function(index, value) {
			this.put(value);
		});
		
		//Reset discard pile
		this.player.discardPile = new Array();

		//Fire event
		$("#player_events").trigger("onReclaim", [this.player.index]);
	}
});

var Hand = Class.extend({
	init: function(player) {
		this.handSize = 5;
		this.player = player;
		this.cards = new Array();
	},
	fill: function() {
		//Draw handSize cards
		this.player.deck.draw(this.handSize);
	},
	//Pass in -1 to discard entire hand
	discard: function(quantity) {
		//Select cards from hand to discard
		if(quantity < 0) {
			//Add entire hand to discard pile
			$.each(this.cards, function(index, value) {
				//Fire event
				$("#player_events").trigger("onDiscard", [this.player.index, value]);
				
				this.player.discardPile.put(value);
			});
			
			//Reset hand
			this.cards = new Array();
		} else {
			//TODO: Need player input here
		}
	}
});

var DiscardPile = Class.extend({
	init: function(player) {
		this.player = player;
		this.cards = new Array();
	},
	//Supports passing in an arbitrary amount of Cards
	put: function() {
		$.each(arguments, function(index, value) {
			this.cards.push(value);
		});
	}
});

var PlayField = Class.extend({
	init: function(player) {
		this.player = player;
		this.cards = new Array();
	}
});

var Player = Class.extend({
	init: function(index, name) {
		this.index = index; //Player number
		this.name = name;
		this.deck = new Deck(this);
		this.hand = new Hand(this);
		this.discardPile = new DiscardPile(this);
		this.playField = new PlayField(this);

		//Set up resources
		this.resetResources();
		
		//Fire event
		$("#player_events").trigger("onNewPlayer", [this.index, this.name, this.actions, this.money, this.buy]);

		this.fillStartingDeck();
	},
	resetResources: function() {
		this.money = 0;
		this.actions = 1;
		this.buy = 1;
	},
	endTurn: function() {
		//Discard hand
		this.hand.discard(-1);

		//Draw new hand
		this.deck.draw(this.hand.handSize);

		//Clear money/actions/buy
		this.resetResources();
	},
	playCard: function(card) {
		//TODO: Process effects

		//Fire event 
		$("#player_events").trigger("onPlayCard", [this.player.index, card]);
	},
	fillStartingDeck: function() {
		for(var x = 0;x < 7;x++) {
			this.deck.cards.push(new COPPER());
		}

		for(var x = 0;x < 3;x++) {
			this.deck.cards.push(new ESTATE());
		}

		//Shuffle!
		this.deck.cards.shuffle();
	}
});